package com.gao.window;

import com.gao.util.MessageUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.wm.ToolWindow;

import javax.swing.*;
import java.awt.*;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class SqlTransform {

    private JPanel sqlTransform;
    private JPanel panel2;
    private JTextArea result;
    private JButton transform;
    private JButton copy;
    private JTextArea params;
    private JTextArea precompileSql;
    private JButton clear;
    MessageUtil messageUtil;

    private static String command = "call";

    public SqlTransform(Project project, ToolWindow toolWindow) {

        init();

        // sql 转换
        transform.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                dealSql();
            }
        });
        // 复制
        copy.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
                Transferable transferable = new StringSelection(result.getText());
                clipboard.setContents(transferable, null);
            }
        });
        clear.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                precompileSql.setText("");
                params.setText("");
                result.setText("");
            }
        });
    }

    public void init() {
        messageUtil = new MessageUtil();
    }

    public void dealSql() {
        Pattern pattern = Pattern.compile("\\?");
        Pattern pattern1 = Pattern.compile("^\\d{4}-\\d{2}-\\d{2}$"); // yyyy-mm-dd
        Pattern pattern2 = Pattern.compile("^\\d{4}-\\d{2}-\\d{2}(\\s*)\\d{2}:\\d{2}:\\d{2}.\\d[0-9]*$"); //yyyy-mm-dd hh:mm:ss.ssss
        String strSql = precompileSql.getText();
        String paramsSql = params.getText();
        String sqlData = result.getText();
        String param = "";
        if (strSql == null) {
            strSql = "";
        }
        if (params == null) {
            paramsSql = "";
        }
        if (sqlData == null) {
            sqlData = "";
        }
        paramsSql = paramsSql.trim().replaceAll("\\[", "").replaceAll("\\]", "");
        if (strSql.length() > 0 && paramsSql.length() > 0) {
            try {
                String[] paramList =  paramsSql.split(",", -1); // -1不忽略最后的空字符
                // 如果是 SP 的 call 命令
                if (strSql.startsWith(command) || strSql.startsWith(command.toUpperCase())) {
                    dealSp(strSql, paramList);
                    return;
                }
                //校验数量
                int paramCount = paramList.length;
                int matcherCount = 0;
                Matcher matcher = pattern.matcher(strSql);
                while (matcher.find()) {
                    matcherCount++;
                }
                if (paramCount != matcherCount) {
                    throw new RuntimeException();
                }
                //处理参数
                for (int i = 0; i < paramList.length; i++) {
                    param = paramList[i].trim();
                    Matcher matcher1 = pattern1.matcher(param);
                    Matcher matcher2 = pattern2.matcher(param);
                    if (matcher1.find()) {
                        paramList[i] = "DATE'" + param + "'";
                    } else if (matcher2.find()){
                        paramList[i] = "timestamp'" + param + "'";
                    } else if ("".equals(param) ) {
                        paramList[i] = "NULL";
                    } else {
                        paramList[i] = "'" + param + "'";
                    }

                }
                StringBuffer sb = new StringBuffer();
                Matcher matcher2 = pattern.matcher(strSql);
                int index = 0;
                while (matcher2.find()) {
                    matcher2.appendReplacement(sb, paramList[index]);
                    index++;
                }
                matcher2.appendTail(sb);
                sqlData = sb.toString();
            } catch(Exception e) {
                sqlData = "待替换参数和SQL参数数量不一致";
                e.printStackTrace();
            }
        }
        result.setText(sqlData);
    }

    /**
     * 处理 CALL sp 的SQL 替换
     * @param sql
     * @param paramList
     */
    public void dealSp(String sql, String[] paramList) {
        Pattern pattern1 = Pattern.compile("^\\d{4}-\\d{2}-\\d{2}$"); // yyyy-mm-dd
        Pattern pattern2 = Pattern.compile("^\\d{4}-\\d{2}-\\d{2}(\\s*)\\d{2}:\\d{2}:\\d{2}.\\d[0-9]*$"); //yyyy-mm-dd hh:mm:ss.ssss
        String param = "";
        StringBuilder sqlData = new StringBuilder();
        sqlData.append(sql).append("(");
        //处理参数
        for (int i = 0; i < paramList.length; i++) {
            param = paramList[i].trim();
            Matcher matcher1 = pattern1.matcher(param);
            Matcher matcher2 = pattern2.matcher(param);
            if (matcher1.find()) {
                param = "DATE'" + param + "'";
            } else if (matcher2.find()){
                param = "timestamp'" + param + "'";
            } else if ("".equals(param) ) {
                param = "NULL";
            } else {
                param = "'" + param + "'";
            }
            sqlData.append(param);
            sqlData.append((i != paramList.length - 1) ? "," : "");
        }
        sqlData.append(")");
        result.setText(sqlData.toString());
    }

    public JPanel getSqlTransform() {
        return sqlTransform;
    }
}
